import sun.nio.ch.sctp.SctpNet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoServer {
    private ServerSocket serverSocket=null;
    private ExecutorService service= Executors.newCachedThreadPool();
    public TcpEchoServer(int port) throws IOException{
        serverSocket=new ServerSocket(port);
    }

    public void  start() throws IOException {
        System.out.println("服务器启动");
        while (true){
            Socket clientSocket=serverSocket.accept();
            //使用线程池创建问题
            service.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        processConnection(clientSocket);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("[%s:%d] 客户端上线！\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
        //接下来就可以读取请求，根据请求计算响应，返回响应，然后进行老三步
        //Socket对象内部包含了两个字节流对象，可以把这俩字节流获取到，完成后，续写读写操作。
        try(InputStream inputStream=clientSocket.getInputStream();
            OutputStream outputStream=clientSocket.getOutputStream()) {
            //一次连接中，可能涉及到多次请求/响应
            while (true) {
                //1.读取请求并且解析，为了读取方便，使用Scanner
                Scanner scanner = new Scanner(inputStream);
                if (!scanner.hasNext()) {
                    //1.读取完毕，客户端下线
                    System.out.printf("[%s:%d]客户端下线！\n", clientSocket.getInetAddress().toString(), clientSocket.getPort());
                    break;
                }
                //这个代码暗含一个约定，客户端发来的请求，得到的文本数据，同时还得是带有空白符号进行分隔（比如换行）
                String request = scanner.next();
                //2.根据请求计算响应
                String response = process(request);
                //3.把响应写回客户端，把OutputStream使用PrinterWriter包裹一下，方便进行发数据
                PrintWriter writer = new PrintWriter(outputStream);
                //使用PrintWriter的println方法，把响应返回给客户端。
                //此处用println，而不是print就是为了在结尾加上\n，方便客户端读取响应，用Scanner.next()读取
                writer.println(response);
                //这里还需要加上"刷新缓冲区操作"
                writer.flush();
                //日志，打印当前的请求详情
                System.out.printf("[%s:%d] req:%s,resp:%s\n", clientSocket.getInetAddress().toString(), clientSocket.getPort(), request, response);
            }
            }
        catch (IOException e){
            e.printStackTrace();
        }finally {
            //在finally中加上close操作，确保当前socket被及时关闭
            clientSocket.close();
        }
    }
    public String process(String request){
        return  request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer tcpEchoServer=new TcpEchoServer(9090);
        tcpEchoServer.start();
    }










}
